﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EvoAlgLib
{
    public class GenArrayCrossover : Crossover
    {
        private double p_cross;
        private IndFactory indFactory;
        private bool alwaysMutate;

        public GenArrayCrossover(IndFactory _indFactory, double _p_cross, bool _alwaysMutate)
        {
            this.p_cross = _p_cross;
            this.indFactory = _indFactory;
            this.alwaysMutate = _alwaysMutate;
        }
        
        public List<Individual> cross(List<Individual> parents)
        {
            List<Individual> ans = new List<Individual>();
            if (LibStatics.getRandomizer().NextDouble() > this.p_cross)
            {
                foreach (Individual parent in parents)
                    if (alwaysMutate)
                        ans.Add((this.indFactory.getIndividual(parent)).mutate());
                    else
                        ans.Add(this.indFactory.getIndividual(parent));
            }
            else
            {
                if (parents.Count == 2)
                {
                    Individual offspring0 = this.indFactory.getIndividual(parents[0]);
                    Individual offspring1 = this.indFactory.getIndividual(parents[1]);

                    int place = LibStatics.getRandomizer().Next(((int[])parents[1].getGenotype()).Length);
                    for (int i = 0; i < place; ++i)
                    {
                        ((int[])offspring0.getGenotype())[i] = ((int[])parents[1].getGenotype())[i];
                        ((int[])offspring1.getGenotype())[i] = ((int[])parents[0].getGenotype())[i];
                    }

                    //if crossover accured => mutate
                    offspring0.mutate();
                    offspring1.mutate();

                    ans.Add(offspring0);
                    ans.Add(offspring1);
                }
                else
                {
                    throw new System.ArgumentException("List must contain exactly 2 BinaryIndividual", "original");
                }

            }
            return ans;
        }
    }
}
